package com.xuecheng.content.service.jobhandler;

import com.xuecheng.base.exception.XueChengPlusException;
import com.xuecheng.content.feignclient.SearchServiceClient;
import com.xuecheng.content.mapper.CoursePublishMapper;
import com.xuecheng.content.mapper.CoursePublishPreMapper;
import com.xuecheng.content.model.po.CourseIndex;
import com.xuecheng.content.model.po.CoursePublish;
import com.xuecheng.content.service.CoursePublishService;
import com.xuecheng.messagesdk.model.po.MqMessage;
import com.xuecheng.messagesdk.service.MessageProcessAbstract;
import com.xuecheng.messagesdk.service.MqMessageService;
import com.xxl.job.core.context.XxlJobHelper;
import com.xxl.job.core.handler.annotation.XxlJob;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.File;

/**
 * @author woldier
 * @version 1.0
 * @description 课程发布任务实现类
 * @date 2023/3/27 10:27
 **/
@Component
@Slf4j
public class CoursePublishTask extends MessageProcessAbstract {

    @Autowired
    CoursePublishService coursePublishService;

    @Autowired
    SearchServiceClient searchServiceClient;

    @Autowired
    CoursePublishMapper coursePublishMapper;


    /**
     * @description 任务执行 重写jar包中的 抽象方法执行类
     * @param
     * @return boolean
     * @author: woldier
     * @date: 2023/3/27 10:28
     */
    // 任务调度入口
    @XxlJob("CoursePublishJobHander")
    public void coursePublishJobHandler() throws Exception {
        // 分片参数
        int shardIndex = XxlJobHelper.getShardIndex();
        int shardTotal = XxlJobHelper.getShardTotal();
        // 调用抽象类的方法执行任务
        process(shardIndex,shardTotal,"course_publish",30,60);
    }
    @Override
    public boolean execute(MqMessage mqMessage) {
        //消息id
        Long id = mqMessage.getId();
        //取出对应的course 这里我们约定课程id存在于message表的 businessKey1 字段
        Integer courseId = Integer.valueOf(mqMessage.getBusinessKey1());

        //执行阶段1 ,静态化页面上传到minio
        generateCourseHtml(mqMessage,courseId);
        //执行阶段2 , 写入 elasticsearch
        saveCourseIndex(mqMessage,courseId);
        //执行阶段3 , 写入redis
        saveCourseCache(mqMessage,courseId);
        return true;
    }
    //生成课程静态化页面并上传至文件系统
    public void generateCourseHtml(MqMessage mqMessage, long courseId) {
        log.debug("开始进行课程静态化,课程id:{}", courseId);
        //消息id
        Long id = mqMessage.getId();
        //消息处理的service
        MqMessageService mqMessageService = this.getMqMessageService();
        //消息幂等性处理  查询数据库 找到该阶段的执行状态
        int stageOne = mqMessageService.getStageOne(id);
        if (stageOne > 0) {
            log.debug("课程静态化已处理直接返回，课程id:{}", courseId);
            return;
        }
        //生成静态化页面
        File file = coursePublishService.generateCourseHtml(courseId);
        //上传静态化页面
        if(file!=null){
            coursePublishService.uploadCourseHtml(courseId,file);
        } else {
            XueChengPlusException.cast("生成的静态html课程资源为空");
        }
        //保存第一阶段状态
        mqMessageService.completedStageOne(id);
    }

    //保存课程索引信息
    public void saveCourseIndex(MqMessage mqMessage,long courseId){
        log.debug("将课程课程索引信息保存至ES,课程id:{}",courseId);
        //消息id
        Long id = mqMessage.getId();
        //消息处理的service
        MqMessageService mqMessageService = this.getMqMessageService();
        //消息幂等性处理  查询数据库 找到该阶段的执行状态
        int stageTwo = mqMessageService.getStageTwo(id);
        if (stageTwo > 0) {
            log.debug("课程课程索引信息保存至ES，课程id:{}", courseId);
            return;
        }
        // 取出课程发布信息
        CoursePublish coursePublish = coursePublishMapper.selectById(courseId);
        // 拷贝信息至课程索引对象
        CourseIndex courseIndex = new CourseIndex();
        BeanUtils.copyProperties(coursePublish,courseIndex);
        // 远程调用搜索服务api添加课程信息到索引
        Boolean add = searchServiceClient.add(courseIndex);
        if(!add){
            XueChengPlusException.cast("添加索引失败");
        }
        //保存第二阶段状态
        mqMessageService.completedStageTwo(id);
    }

    //将课程信息缓存至redis
    public void saveCourseCache(MqMessage mqMessage,long courseId){
        log.debug("将课程信息缓存至redis,课程id:{}",courseId);
        // TODO 将课程信息缓存至redis
        log.debug("开始进行课程信息缓存至redis,课程id:{}", courseId);
        //消息id
        Long id = mqMessage.getId();
        //消息处理的service
        MqMessageService mqMessageService = this.getMqMessageService();
        //消息幂等性处理  查询数据库 找到该阶段的执行状态
        int stageThree = mqMessageService.getStageThree(id);
        if (stageThree > 0) {
            log.debug("课程静态化已处理直接返回，课程id:{}", courseId);
            return;
        }
        /*try {
            TimeUnit.SECONDS.sleep(2);
        } catch (InterruptedException e) {
            throw new RuntimeException(e);
        }*/
        //保存第三阶段状态
        mqMessageService.completedStageThree(id);
    }
}
